package cn.tedu.charging.order.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * rabbit-mq 配置类
 * 连接信息 用户名 密码
 * 定义 队列 交换机 并且绑定
 */
@Configuration
public class RabbitMQConfig {

    /**
     * 定义正常订单EXCHANGE
     */
    //RabbitMQOrderProducer里需要把信息发给配置类的这个正常订单交换机属性，所以前缀用public
    public static final String ORDER_EXCHANGE = "order.exchange";   //名字随便起的，可以用. 也可以用 _

    /**
     * 定义正常订单RoutingKey
     */
    //前缀public理由同上
    public static final String ORDER_ROUTING_KEY = "order.routing.key";

    /**
     * 定义正常订单队列
     */
    private static final String ORDER_QUEUE = "order.queue";

    /**
     * 定义死信订单EXCHANGE
     */
    private static final String ORDER_DEAD_LETTER_EXCHANGE = "order.dead.letter.exchange";

    /**
     * 定义死信订单RoutingKey
     */
    private static final String ORDER_DEAD_LETTER_ROUTING_KEY = "order.dead.letter.routing_key";

    /**
     * 定义死信订单队列
     */
    public static final String ORDER_DEAD_LETTER_QUEUE = "order.dead.letter.queue";


    /**
     * 定义订单交换机
     */
    @Bean
    public DirectExchange orderExchange(){
        return new DirectExchange(ORDER_EXCHANGE);  //正常订单exchange
    }

    /**
     * 定义订单队列
     */
    @Bean
    public Queue orderQueue() {     //是在定义解决方案图中的绿色queue
        Map<String, Object> args = new HashMap<String, Object>();
        args.put("x-dead-letter-exchange", ORDER_DEAD_LETTER_EXCHANGE);     //将死信订单EXCHANGE存入Map中
        args.put("x-dead-letter-routing-key", ORDER_DEAD_LETTER_ROUTING_KEY);
        //模拟充电充满需要 2分钟  2*60*1000毫秒
        Integer ttl =  2 * 60 * 1000;
        //指定消息的存活时间
        args.put("x-message-ttl", ttl);
        //惰性队列,在消息很多的时候,存储到磁盘,避免消息积压,占用内存
        args.put("x-queue-mode", "lazy");
        //消息持久化 不能丢失
        Boolean durable  = true;
        return new Queue(ORDER_QUEUE,durable,true,false,args);  //正常订单队列  第3个参数true干啥的？？？与死信队列最大的区别是最后一个参数
    }

    /**
     * 把订单队列绑定到订单交换机
     */
    @Bean
    public Binding orderBinding(){
        return BindingBuilder.bind(orderQueue()).to(orderExchange()).with(ORDER_ROUTING_KEY);   //意思明白，但代码出来后是啥样？拼成啥样？
    }

    /**
     * 定义死信的交换机
     */
    @Bean
    public DirectExchange deadLetterExchange(){
        return new DirectExchange(ORDER_DEAD_LETTER_EXCHANGE,true,false);
    }

    /**
     * 定义死信的队列
     */
    @Bean
    public Queue deadLetterQueue(){
        return new Queue(ORDER_DEAD_LETTER_QUEUE,true,false,false);
    }

    /**
     * 将死信队列和死信交换机进行绑定
     */
    @Bean
    public Binding deadLetterBindingDeadLetter(){
        return BindingBuilder.bind(deadLetterQueue()).to(deadLetterExchange()).with(ORDER_DEAD_LETTER_ROUTING_KEY);
    }

}
